// /////////////////////////////////////////////////////////////////////////////
//
// Name:            asEntity.cpp
// Author:          Michael Bartsch (ZCCdark203)
//
// Desc :           Binds the Entity class to AngelScript
//
// License:         Copyright (C) 2009 Michael Bartsch and Contributors
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the zlib/libpng License.
//                  See main.cpp for conditions of distribution and use.
//
// /////////////////////////////////////////////////////////////////////////////

// Include files
#include "asEntity.h"

#ifdef __COMPILE_WITH_ANGELSCRIPT__

#include "asHasEvents.h"
#include "asEntityComponent.h"
#include "asSerializable.h"
#include "../ScriptHelper.h"

#include "../../core/Entity.h"


//! Reference factory for the Entity class.
Entity* createEntity(const std::string &name)
{
    return new Entity(name);
}

//! Wrapper function to allow classes "derived" from the EntityComponent class to be
//! used by the Entity::addComponent
bool addComponent(asIScriptObject *object, Entity *entity)
{
    ScriptedEntityComponent *component = new ScriptedEntityComponent(object);
    bool succeeded = entity->addComponent(component);
    component->drop();

    return succeeded;
}


//! Binds the Entity class to AngelScript.
void bindEntity(asIScriptEngine *engine)
{
    // Forward declarations.
    int r;

    // Bind Entity class (and dependencies).
    r = engine->RegisterObjectType("Entity", sizeof(Entity), asOBJ_REF);
    r = engine->RegisterObjectType("EntityComponent", sizeof(EntityComponent), asOBJ_REF);
    r = engine->RegisterInterface("IEntityComponent");

    // Bind inherited functions.
    bindHasEventsBase<Entity>(engine, "Entity");
    bindSerializableBase<Entity>(engine, "Entity");

    // Set Entity behaviour.
    r = engine->RegisterObjectBehaviour("Entity", asBEHAVE_FACTORY, "Entity@ f(const string &in)",
                                        asFUNCTION(createEntity), asCALL_CDECL); assert(r >= 0);

    r = engine->RegisterObjectMethod("Entity", "Entity& opAssign(const Entity &in)",
                                        asFUNCTION(assignT<Entity>), asCALL_CDECL_OBJLAST); assert(r >= 0);

    // Bind Entity class functions.
    r = engine->RegisterObjectMethod("Entity", "u32 getID()",
                                     asMETHOD(Entity, getID), asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "const string& getName()",
                                     asMETHOD(Entity, getName), asCALL_THISCALL); assert(r >= 0);

    r = engine->RegisterObjectMethod("Entity", "bool addChild(Entity @+)",
                                     asMETHOD(Entity, addChild), asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "bool addComponent(EntityComponent @+)",
                                     asMETHOD(Entity, addComponent), asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "bool addComponent(IEntityComponent @+)",
                                     asFUNCTION(addComponent), asCALL_CDECL_OBJLAST); assert(r >= 0);

    r = engine->RegisterObjectMethod("Entity", "AssetGroup@ getAssetGroup()",
                                     asMETHOD(Entity, getAssetGroup), asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "Entity@ getChild(const u32)",
                                     asMETHODPR(Entity, getChild, (const u32), Entity*),
                                     asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "Entity@ getChild(const string &in)",
                                     asMETHODPR(Entity, getChild, (const std::string &), Entity*),
                                     asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "EntityComponent@ getComponent(const u32)",
                                     asMETHODPR(Entity, getComponent, (const u32), EntityComponent*),
                                     asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "EntityComponent@ getComponent(const string &in)",
                                     asMETHODPR(Entity, getComponent, (const std::string &), EntityComponent*),
                                     asCALL_THISCALL); assert(r >= 0);

    r = engine->RegisterObjectMethod("Entity", "Entity@ getParent()",
                                     asMETHOD(Entity, getParent), asCALL_THISCALL); assert(r >= 0);

    r = engine->RegisterObjectMethod("Entity", "const vector3df& getAbsolutePosition()",
                                     asMETHOD(Entity, getAbsolutePosition), asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "const vector3df& getPosition()",
                                     asMETHOD(Entity, getPosition), asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "const vector3df& getAbsoluteRotation()",
                                     asMETHOD(Entity, getAbsoluteRotation), asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "const vector3df& getRotation()",
                                     asMETHOD(Entity, getRotation), asCALL_THISCALL); assert(r >= 0);

    r = engine->RegisterObjectMethod("Entity", "void removeChildren()",
                                     asMETHOD(Entity, removeChildren), asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "void removeComponents()",
                                     asMETHOD(Entity, removeComponents), asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "bool removeChild(Entity @+)",
                                     asMETHODPR(Entity, removeChild, (Entity*), bool),
                                     asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "bool removeChild(const u32)",
                                     asMETHODPR(Entity, removeChild, (const u32), bool),
                                     asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "bool removeChild(const string &in)",
                                     asMETHODPR(Entity, removeChild, (const std::string&), bool),
                                     asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "bool removeComponent(EntityComponent @+)",
                                     asMETHODPR(Entity, removeComponent, (EntityComponent*), bool),
                                     asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "bool removeComponent(const u32)",
                                     asMETHODPR(Entity, removeComponent, (const u32), bool),
                                     asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "bool removeComponent(const string &in)",
                                     asMETHODPR(Entity, removeComponent, (const std::string&), bool),
                                     asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "void removeParent()",
                                     asMETHOD(Entity, removeParent), asCALL_THISCALL); assert(r >= 0);

    r = engine->RegisterObjectMethod("Entity", "void setParent(Entity @+)",
                                     asMETHOD(Entity, setParent), asCALL_THISCALL); assert(r >= 0);

    r = engine->RegisterObjectMethod("Entity", "void setAbsolutePosition(vector3df &in)",
                                     asMETHOD(Entity, setAbsolutePosition), asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "void setPosition(vector3df &in)",
                                     asMETHOD(Entity, setPosition), asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "void setAbsoluteRotation(vector3df &in)",
                                     asMETHOD(Entity, setAbsoluteRotation), asCALL_THISCALL); assert(r >= 0);
    r = engine->RegisterObjectMethod("Entity", "void setRotation(vector3df &in)",
                                     asMETHOD(Entity, setRotation), asCALL_THISCALL); assert(r >= 0);
}

#endif // __COMPILE_WITH_ANGELSCRIPT__

// End of File
